<template>
  <div class="view">
    <!-- Step 1 创建容器 -->
    <div ref="container" id="container" style="width: 910px; height: 800px;"></div>
  </div>
</template>
<script>
// Step 2 准备数据
import { Graph } from '@antv/x6'
export default {
  name: "xsixView",
  data() {
    return {
      graph: null,//创建画布
      source: null,//子级1
      target: null,//子级2
      parent: null,//父级
      data: {
      }
    }
  },
  created() {

  },
  mounted() {
    this.initGraph()
  },
  methods: {
    initGraph() {
      // Step 3 渲染画布
      this.graph = new Graph({
        container: document.getElementById('container'),
        grid: true,
        embedding: {
          enabled: true,
        },
        highlighting: {
          embedding: {
            name: 'stroke',
            args: {
              padding: -1,
              attrs: {
                stroke: '#73d13d',
              },
            },
          },
        },
      }),
        // 父级
        this.parent = this.graph.addNode({
          x: 40,
          y: 40,
          width: 360,
          height: 160,
          zIndex: 1,
          label: 'Parent',
          attrs: {
            body: {
              fill: '#fffbe6',
              stroke: '#ffe7ba',
            },
            label: {
              fontSize: 12,
            },
          },
        }),
        // 子级1
        this.source = this.graph.addNode({
          x: 80,
          y: 100,
          width: 80,
          height: 40,
          label: 'Child',
          zIndex: 10,
          attrs: {
            body: {
              stroke: 'none',
              fill: '#3199FF',
            },
            label: {
              fill: '#fff',
              fontSize: 12,
            },
          },
        }),
        // 子级2
        this.target = this.graph.addNode({
          x: 280,
          y: 80,
          width: 80,
          height: 40,
          label: 'Child',
          zIndex: 10,
          attrs: {
            body: {
              stroke: 'none',
              fill: '#47C769',
            },
            label: {
              fill: '#fff',
              fontSize: 12,
            },
          },
        })
      this.parent.addChild(this.source)
      this.parent.addChild(this.target)
      let ctrlPressed = false
      const embedPadding = 20
      this.graph.on('node:embedding', ({ e }) => {
        ctrlPressed = e.metaKey || e.ctrlKey
      })

      this.graph.on('node:embedded', () => {
        ctrlPressed = false
      })

      this.graph.on('node:change:size', ({ node, options }) => {
        if (options.skipParentHandler) {
          return
        }

        const children = node.getChildren()
        if (children && children.length) {
          node.prop('originSize', node.getSize())
        }
      })

      this.graph.on('node:change:position', ({ node, options }) => {
        if (options.skipParentHandler || ctrlPressed) {
          return
        }

        const children = node.getChildren()
        if (children && children.length) {
          node.prop('originPosition', node.getPosition())
        }

        const parent = node.getParent()
        if (parent && parent.isNode()) {
          let originSize = parent.prop('originSize')
          if (originSize == null) {
            originSize = parent.getSize()
            parent.prop('originSize', originSize)
          }

          let originPosition = parent.prop('originPosition')
          if (originPosition == null) {
            originPosition = parent.getPosition()
            parent.prop('originPosition', originPosition)
          }

          let x = originPosition.x
          let y = originPosition.y
          let cornerX = originPosition.x + originSize.width
          let cornerY = originPosition.y + originSize.height
          let hasChange = false

          const children = parent.getChildren()
          if (children) {
            children.forEach((child) => {
              const bbox = child.getBBox().inflate(embedPadding)
              const corner = bbox.getCorner()

              if (bbox.x < x) {
                x = bbox.x
                hasChange = true
              }

              if (bbox.y < y) {
                y = bbox.y
                hasChange = true
              }

              if (corner.x > cornerX) {
                cornerX = corner.x
                hasChange = true
              }

              if (corner.y > cornerY) {
                cornerY = corner.y
                hasChange = true
              }
            })
          }
          if (hasChange) {
            parent.prop(
              {
                position: { x, y },
                size: { width: cornerX - x, height: cornerY - y },
              },
              { skipParentHandler: true },
            )
          }
        }
      })
    }
  }
}
</script>
<style lang="less" scoped>
.view {
  height: 100%;
  width: 100%;
}
</style>

